/* ThyTube - A Firefox add-on for YouTube
   (c) 2007 Reinis Ivanovs <dabas@untu.ms>

   Available under the BSD-new terms.
*/


// For debugging
function _() {
    if (typeof top.Firebug == 'undefined')
        return;
    top.Firebug.Console.log(arguments);
}


var ThyTube = {
    // The pattern URIs are matched against
    patt: /http:\/\/((w{3}|br|fr|ie|it|jp|nl|pl|es|uk)\.)?youtube\.com\/watch[^_]/,
    // Where the user styles are kept
    css: 'chrome://thytube/content/thytube.css',
    prefs: Components.classes['@mozilla.org/preferences-service;1']
        .getService(Components.interfaces.nsIPrefService)
        .getBranch('extensions.thytube.'),
    players: [
        function(src) {
            return src.replace('/player2.swf?',
                'http://thytube.googlecode.com/svn/content/player.swf?0.2&');
        }, function(src) {
            return src + '&fs=1';
        }],
    init: function() {
        // http://developer.mozilla.org/en/docs/Using_the_Stylesheet_Service
        var sss = Components.classes['@mozilla.org/content/style-sheet-service;1']
                .getService(Components.interfaces.nsIStyleSheetService),
            ios = Components.classes['@mozilla.org/network/io-service;1']
                .getService(Components.interfaces.nsIIOService),
            uri = ios.newURI(this.css, null, null);
        // Only register the user style once
        if(!sss.sheetRegistered(uri, sss.USER_SHEET))
            sss.loadAndRegisterSheet(uri, sss.USER_SHEET);
        // Add a normal listener to the browser
        getBrowser().addEventListener('DOMContentLoaded',
            function(e) { ThyTube.main(e); }, false);
    },
    main: function(e) {
        // Get the document element
        var doc = e.originalTarget;
        // Halt if it's not a HTML document or a YouTube video
        if (!(doc instanceof HTMLDocument) || !this.patt.test(doc.location) ||
            (doc.location + '').indexOf('&v3') != -1)
            return;
        // Get the elements from the document
        var movie = doc.getElementById('movie_player'),
            sidebar = doc.getElementById('aboutExploreDiv'),
            root = doc.lastChild;
        if (response = doc.getElementById('vResponseParent')) {
            response.parentNode.parentNode.style.paddingBottom = '105px';
        }
        // Load honors when you scroll the info panel
        doc.getElementById('actionsAndStatsDiv').setAttribute('onscroll',
            'toggleFullStats(); this.onscroll = "";');
        // Set the proper size
        movie.setAttribute('width', '100%');
        movie.setAttribute('height', '100%');
        // Test feature
        //~ doc.addEventListener('keypress', function(e) {
            //~ movie.toggle_pause();
            //~ e.preventDefault();
            //~ return false;
        //~ }, false);
        // Use the appropriate player
        var src = this.players[this.prefs.getIntPref('player')](movie.src);
        movie.setAttribute('src', src);
        // Show the player
        movie.style.display = 'block';
        // This loads the additional thunbnails when the sidebar is scrolled
        sidebar.setAttribute('onscroll',
            'render_full_side(); this.onscroll = "";');
        // Do the rest with the document
        this.build(doc);
    },
    // Mess with the DOM of the document
    build: function(doc) {
        var title = doc.getElementById('video_title'),
            ns_uri = 'http://www.w3.org/1999/xhtml',
            maximize = document.createElementNS(ns_uri, 'span'),
            class_name = 'thytube-maximize',
            maximize_text = 'Maximize';
        // The maximize button
        maximize.setAttribute('id', 'thytube-maximize-button');
        // Make it toggle the class name of the body element
        // and the text of the button
        maximize.onclick = function() {
            if (doc.body.className == class_name) {
                doc.body.className = '';
                maximize.firstChild.nodeValue = maximize_text;
            }
            else {
                doc.body.className = class_name;
                maximize.firstChild.nodeValue = 'Restore';
            }
        }
        maximize.appendChild(doc.createTextNode(maximize_text));
        // Insert it in the video title
        title.appendChild(maximize);
        // The download link
        var stats = stats = doc.getElementById('actionsAndStatsDiv'),
            download = document.createElementNS(ns_uri, 'div'),
            link = document.createElementNS(ns_uri, 'a'),
            src = doc.getElementById('movie_player').getAttribute('flashvars'),
            // Find the relevant parts of the video URI
            parts = src.match(/(video_id=\S+?)&.*(t=\S+?)&/);
        link.appendChild(document.createTextNode('Download Video'));
        // Drop the first part
        parts.shift();
        // Set the address
        link.href = 'get_video?' + parts.join('&');
        download.className = 'actionRow';
        download.id = 'thytube-download';
        download.appendChild(link);
        // Find where to insert it in the document
        var children = stats.childNodes;
        for (var i = 0, n = children.length, q = 0; i < n; i++) {
            // Skip if it's not a div element
            if (children[i].nodeType != 1 || children[i].tagName != 'DIV')
                continue;
            q += 1;
            // Insert the download link in the 4th column
            if (q == 4) {
                children[i].appendChild(download);
            }
            // Insert the comments link in the 6th column
            else if (q == 6) {
                var html = children[i].innerHTML;
                children[i].innerHTML = html.replace(/(Comments):/,
                    '<a href="#commentsDiv" id="thytube-comm">$1</a>:');
                // Get the link we created from the DOM
                var comm = doc.getElementById('thytube-comm');
                // Make it toggle the comments
                comm.setAttribute('onclick',
                    'var comm = document.getElementById("commentsDiv"); ' +
                    'comm.className = (comm.className == "on") ? "" : "on"; ' +
                    'window.scrollTo(0, document.lastChild.offsetHeight); ' +
                    'return false;');
                // Stop iterating
                break;
            }
        }
    },
    // Just in case, so there are no memoryleaks
    stop: function() {
        for (var x in ThyTube) {
            ThyTube[x] = null;
            delete ThyTube[x];
        }
    }
}

// Add the chrome listeners
window.addEventListener('load', function(e) { ThyTube.init(e); }, false);
window.addEventListener('unload', function(e) { ThyTube.stop(e); }, false);
